package com.ljx.recruitment.user.service.impl.auth;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.setting.yaml.YamlUtil;
import com.ljx.recruitment.common.exception.ApiException;
import com.ljx.recruitment.user.domain.entity.User;
import com.ljx.recruitment.user.domain.vo.req.AuthReq;
import com.ljx.recruitment.user.domain.vo.req.UserSubmitReq;
import com.ljx.recruitment.user.domain.vo.resp.UserResp;
import com.ljx.recruitment.user.service.AuthService;
import com.ljx.recruitment.user.service.UserService;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Objects;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-10-20  18:45
 */
public class WxAuthServiceImpl implements AuthService {

    private final RestTemplate restTemplate;

    private final UserService userService;

    private String wxAppid;

    private String wxRedirectUri;

    private String wxAppSecret;

    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
    private static final String REQUEST_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";

    public WxAuthServiceImpl() {
        this.restTemplate = SpringUtil.getBean(RestTemplate.class);
        this.userService = SpringUtil.getBean(UserService.class);
        Dict dict = YamlUtil.loadByPath("application.yml");
        Map<String, Object> wechatConfig = (Map<String, Object>) dict.get("wechat");
        this.wxAppid = (String) wechatConfig.get("appid");
        this.wxAppSecret = (String) wechatConfig.get("appSecret");
        this.wxRedirectUri = (String) wechatConfig.get("redirectUri");
    }

    @Override
    public User tryToLogin(AuthReq authReq) {
        if (Objects.isNull(authReq.getCode())){
            throw new ApiException("关键参数不能为空");
        }

        Map<String, String> map = getAccessToken(authReq.getCode());
        if (Objects.isNull(map) || map.isEmpty()){
            throw new ApiException("请求access_token出错");
        }
        Map<String, String> userMap = getUserInfo(map.get("access_token"), map.get("openid"));
        if (Objects.isNull(userMap) || userMap.isEmpty()){
            throw new ApiException("请求用户信息出错");
        }

        User buildUser = buildByWxResp(userMap, Long.parseLong(authReq.getWxState()));
        UserResp userResp = userService.submitByUsername(BeanUtil.copyProperties(buildUser, UserSubmitReq.class));

        return BeanUtil.copyProperties(userResp, User.class);
    }

    private User buildByWxResp(Map<String, String> userMap, Long tenantId) {
        User user = new User();
        user.setAvatar(userMap.get("headimgurl"));
        user.setNickname(userMap.get("nickname"));
        user.setUsername(userMap.get("openid"));
        user.setTenantId(tenantId);
        return user;
    }

    private Map<String, String> getUserInfo(String accessToken, String openid) {
        String finalUrl = String.format(REQUEST_USER_INFO, accessToken, openid);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(finalUrl, HttpMethod.POST, String.class);

        return JSONUtil.toBean(responseEntity.getBody(), Map.class);
    }

    private Map<String, String> getAccessToken(String code) {
        String finalUrl = String.format(ACCESS_TOKEN_URL, wxAppid, wxAppSecret, code);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(finalUrl, HttpMethod.POST, String.class);

        return JSONUtil.toBean(responseEntity.getBody(), Map.class);
    }

    @Override
    public User tryToRegister(AuthReq authReq) {
        return null;
    }



}
